import { spawn, spawnSync } from "child_process";
import { existsSync, readFileSync, writeFileSync } from "fs";
import path, { resolve } from 'path';
import PackUtil from "../utils/PackUtil";
import { BasePlatform } from "./BasePlatform";
import { ChannelInfo } from "./PlatformConfig";
import * as fs from 'fs';

export class UnityByteDance extends BasePlatform {

    public async beforeStartBuild() {
        console.log("Starting beforeStartBuild for UnityByteDance...");
        await super.beforeStartBuild();
        console.log("Completed beforeStartBuild for UnityByteDance.");
    }

    public async buildUnity(): Promise<boolean> {
        return new Promise<boolean>((resolve, reject) => {
            try {
                console.log("\n=== Unity Build Configuration ===");
                console.log("Project Directory:", this.projectDir);

                // 添加日志文件路径
                const logPath = path.join(this.projectDir, "UnityBuild.log");

                // 修改命令行参数，添加详细日志
                const buildArgs = [
                    '-quit',
                    '-batchmode',
                    '-projectPath',
                    this.projectDir,
                    '-executeMethod',
                    'CommandLineBuild.Main',
                    '-logFile',
                    logPath,
                    '-nographics',  // 添加无图形界面模式
                    '-stackTraceLogType',  // 添加堆栈跟踪
                    'Full'
                ];

                console.log("\n=== Unity Build Command ===");
                console.log("Unity Path:", this.unityEnginePath);
                console.log("Build Arguments:", JSON.stringify(buildArgs, null, 2));
                console.log("Log File Path:", logPath);

                let sp = spawn(this.unityEnginePath, buildArgs, {
                    shell: false,
                    windowsVerbatimArguments: true
                });

                let outputData = '';
                let errorData = '';

                sp.stdout.setEncoding('utf8');
                sp.stdout.on('data', (data) => {
                    outputData += data;
                    console.log("Unity Output:", data.toString());
                });

                sp.stderr.on('data', (data) => {
                    errorData += data;
                    console.error("Unity Error:", data.toString());
                });

                sp.on('error', (err) => {
                    console.error("Spawn Error:", err);
                    reject(err);
                });

                sp.on('exit', async (code, signal) => {
                    console.log(`\n=== Unity Build Process Completed ===`);
                    console.log(`Exit Code: ${code}, Signal: ${signal}`);

                    // 读取日志文件
                    try {
                        if (fs.existsSync(logPath)) {
                            const logContent = fs.readFileSync(logPath, 'utf8');
                            console.log("\n=== Unity Build Log ===");
                            console.log(logContent);
                        } else {
                            console.log("No build log file found at:", logPath);
                        }
                    } catch (error) {
                        console.error("Error reading log file:", error);
                    }

                    if (code === 0) {
                        console.log(`Build successful for channel: ${this.curPackChannel}`);
                        resolve(true);
                    } else {
                        console.error("\n=== Build Error Details ===");
                        console.error("Standard Output:", outputData);
                        console.error("Error Output:", errorData);
                        reject(new Error(`Unity build failed with code ${code}. Check the log for details.`));
                    }
                });

            } catch (error) {
                console.error(`\n=== Unity Build Failed ===`);
                console.error("Error:", error);
                reject(error);
            }
        });
    }

    //将构建目录下的远程资源上传(最好先在打包机上打包一次，提前发现问题)
    public async afterBuildFinish() {
        let channelInfo: ChannelInfo = this.configData.platforms[this.curPackChannel];
        let cdnrespath = channelInfo.remoteDir;

        if (!cdnrespath) {
            console.log('No CDN path specified, skipping CDN operations');
            return;
        }

        console.log('CDN operations starting for path:', cdnrespath);

        try {
            console.log('upload cdn res start');
            try {
                PackUtil.pullCDNRes(cdnrespath);
            } catch (error) {
                console.error('Error during CDN pull:', error);
            }

            try {
                PackUtil.uploadCDNRes(cdnrespath);
            } catch (error) {
                console.error('Error during CDN upload:', error);
            }
            console.log('upload cdn res finish');
        } catch (error) {
            console.error('Error in CDN operations:', error);
        }
    }
}